Various tools exist to allow the compilation and decompilation of software code. A compiler is a software tool that translates (and optionally optimizes) high level languages into low-level instruction sequences that hardware can understand and execute (e.g. an executable file). Compilers are needed by anybody who develops software running on central processing units (CPUs) or graphical processing units (GPUs). These include for example languages such as C# and C++ that run on CPUs as well as other languages such as HLSL, GLSL, and Compute Shaders that run on GPUs. A decompiler does the opposite and is a software tool for taking an executable computer program file and translating it into a computer language source file at a high level. Sometimes the translation is not perfect and the decompiled file is not equivalent to source file that was originally compiled to create the executable file. Decompilers are used to reverse engineer computer programs.
In the world of computer graphics, most computer graphics applications use vectors when performing calculations. Modern processors deal natively with vectors using SIMD, or Single Instruction Multiple Data methodology. This allows a processor, for example, to add two colors as a vector in one operation rather than using the inefficient method of having 4 addition operations (e.g., one addition for each component, including red, green, blue and alpha). This is due in part to the convenient fact that 3D coordinates are naturally in vector format (e.g., x, y, z) and any color can also be thought of as a vector combination of basic colors such as Red (R), Green (G), and Blue (B) with vector formatting (e.g., R, G, B, alpha). SIMD is included in most modern day compilers, however, existing compilers see vectors as an opaque data structure (e.g., the compilers are blind to the components of the vector). Or sometimes the compiler can ‘see’ a value for the vector if all the components of the vector have the same value (making a vector more similar to a scalar value). The opaque nature of the data structure makes optimization by the compiler impossible in some situations since some operations on vectors will only affect a single component and the compiler would not be able to see the modification.
In addition to the values of a vector being opaque to existing compilers, library calls that include mathematical functions (e.g., including square root, sine, cosine, rounding functions, and the like) are also opaque and considered black boxes since a user can link to any library to return a mathematical function. When a function or value is opaque, a compiler cannot assume anything about the function and is limited with the optimizations it can perform. For example, existing compilers have no way of knowing about higher level math such as dot products and cross products, nor do they know about high level math identities such as Lagrange's identity. Existing compilers also have no information on the properties of math functions or how those properties can be used for optimization, for example an existing compiler does not know that the cosine function is symmetric around zero and that the symmetry can be useful in optimization. A compiler would see a cosine function call as a black box function call with no semantic information to use for optimization (e.g., optimizations including the application of trigonometric identities to simplify mathematical expressions).
It will be noted that throughout the appended drawings, like features are identified by like reference numerals.